"use strict";
// const fse = require('fs-extra');
const Command = require("@hcnhistudy/command");
const { getTemplate } = require("./action");
const Package = require("@hcnhistudy/package");
const { spinnerStart, sleep, spawnAsyanc } = require("@hcnhistudy/utils");
const semver = require("semver");
const userHome = require("user-home");
const log = require("@hcnhistudy/log");
const fse = require("fs-extra");
const inquirer = require("inquirer");
const glob = require("glob");
const ejs = require("ejs");

const TYPE_PROJECT = "project";
const TYPE_COMPONENT = "component";

const TEMPLATE_TYPE_NORMAL = "normal"; // 标准安装
const TEMPLATE_TYPE_CUSTOM = "custom"; // 非标准安装
class InitCommand extends Command {
  constructor(argv) {
    // console.log(argv)
    super(argv);
  }
  init() {
    // 把命令结构复制到this上
    let [projectName, cmd] = this._argv;
    this.projectName = projectName;
    Object.keys(cmd).forEach((key) => {
      this[key] = cmd[key];
    });
    // console.log(this._argv);
  }
  async exec() {
    const projectInfo = await this.prepare();
    this.projectInfo = projectInfo;
    await this.downloadTemplate();
    await this.installTemplate();
    // 1.准备阶段
    // 下载模板
    // 安装模板
  }
  async prepare() {
    const template = await getTemplate();
    if (!template || (Array.isArray(template) && template.length === 0)) {
      throw new Error("项目模板不存在");
    }
    this.template = template;
    const localPath = process.cwd();
    console.log(this.isDirEmpty(localPath), localPath);
    let ifContinue = false;
    if (!this.isDirEmpty(localPath)) {
      if (!this.force) {
        ifContinue = (
          await inquirer.prompt({
            type: "confirm",
            name: "ifContinue",
            default: false,
            message: "当前文件不为空，是否继续创建项目",
          })
        ).ifContinue;
      }
      if (!ifContinue) return;
      // console.log(ifContinue);
      if (ifContinue || this.force) {
        const { confirmDelete } = await inquirer.prompt({
          type: "confirm",
          name: "confirmDelete",
          default: false,
          message: "是否确认清空当前目录下的文件?",
        });
        console.log(confirmDelete);
        // 清空当前目录
        // 2.是否启动强制更新

        if (confirmDelete) {
          // 清空当前目录
          const spinner = spinnerStart("正在清空当前目录...");
          fsExtra.emptyDirSync(localPath);
          spinner.stop(true);
        }
        // fse.emptyDirSync(localPath);// 清空文件夹
      }
    } else {
    }
    const projectInfo = await this.getProjectInfo();
    return projectInfo;
    // console.log(template);
  }

  async getProjectInfo() {
    function isValidName(v) {
      return /^[a-zA-Z]+([-][a-zA-Z][a-zA-Z0-9]*|[_][a-zA-Z][a-zA-Z0-9]*|[a-zA-Z0-9])*$/.test(
        v
      );
    }
    let projectInfo = Object.create(null);
    const { type } = await inquirer.prompt({
      type: "list",
      name: "type",
      message: "请选择初始化类型",
      default: TYPE_PROJECT,
      choices: [
        {
          name: "项目",
          value: TYPE_PROJECT,
        },
        {
          name: "组件",
          value: TYPE_COMPONENT,
        },
      ],
    });
    if (type === TYPE_PROJECT) {
      const _projectInfo = await inquirer.prompt([
        {
          type: "input",
          name: "projectName",
          message: "请输入项目名称",
          default: "",
          // 对项目名称约束
          validate: function (v) {
            // 输入的首字符必须为英文字符
            // 尾字符必须为英文或数字，不能为字符
            // 字符仅允许 “-_”
            const done = this.async();
            setTimeout(function () {
              if (!isValidName(v)) {
                return done(`请输入合法的${title}名称`);
              }
              done(null, true);
            }, 0);
            return;
          },
        },
        {
          type: "input",
          name: "projectVersion",
          message: "请输入项目版本号",
          default: "1.0.0",
          validate: function (v) {
            return !!semver.valid(v); // 对版本号校验
          },
        },
        {
          type: "list",
          name: "projectTemplate",
          message: "请选择项目模板",
          default: "",
          choices: this.createTemplateChoices(),
        },
      ]);
      projectInfo = {
        type,
        ..._projectInfo,
      };
    } else if (type === TYPE_COMPONENT) {
    }
    if (projectInfo.projectName) {
      projectInfo.className = require("kebab-case")(
        projectInfo.projectName
      ).replace(/^-/, "");
    }

    if (projectInfo.projectVersion) {
      projectInfo.version = projectInfo.projectVersion;
    }

    if (projectInfo.componentDescription) {
      projectInfo.description = projectInfo.componentDescription;
    }
    return projectInfo;
  }

  createTemplateChoices() {
    return this.template.map((item) => {
      return {
        value: item.npmName,
        name: item.name,
      };
    });
  }

  async downloadTemplate() {
    const { projectTemplate } = this.projectInfo;
    const templateInfo = this.template.find(
      (item) => item.npmName === projectTemplate
    );
    this.templateInfo = templateInfo;
    const targetPath = path.resolve(userHome, ".hcnhistudy-cli", "template");
    const storeDir = path.resolve(
      userHome,
      ".hcnhistudy-cli",
      "template",
      "node_modules"
    );
    const { npmName, version } = templateInfo;
    // console.log(npmName, version);
    const templateNpm = new Package({
      targetPath,
      storeDir,
      packageName: npmName,
      packageVersion: version,
    });
    if (!(await templateNpm.exists())) {
      const spinner = spinnerStart("正在下载模板..."); // 线上进度条
      await sleep();
      try {
        await templateNpm.install();
      } catch (error) {
        throw error;
      } finally {
        spinner.stop(true); // 停止进度条
        if (await templateNpm.exists()) {
          log.success("下载模板成功");
          this.templateNpm = templateNpm;
        }
      }
    } else {
      const spinner = spinnerStart("正在更新模板..."); // 线上进度条
      await sleep();
      try {
        await templateNpm.update();
      } catch (error) {
        throw error;
      } finally {
        spinner.stop(true); // 停止进度条
        if (await templateNpm.exists()) {
          log.success("更新模板成功");
          this.templateNpm = templateNpm;
        }
      }
    }
  }

  async installTemplate() {
    // console.log(this.templateInfo);
    if (this.templateInfo) {
      if (!this.templateInfo.type) {
        this.templateInfo.type = TEMPLATE_TYPE_NORMAL;
      }
      if (this.templateInfo.type === TEMPLATE_TYPE_NORMAL) {
        // 标准安装
        await this.installNormalTemplate();
      } else if (this.templateInfo.type === TEMPLATE_TYPE_CUSTOM) {
        // 自定义安装
        await this.installCustomTemplate();
      } else {
        throw new Error("项目模版类型");
      }
    }
  }
  // 标准安装
  async installNormalTemplate() {
    // console.log(this.templateNpm.cacheFilePath);
    const spinner = spinnerStart("正在安装模版...");
    await sleep();
    let targetPath;
    try {
      // 拷贝当前代码至当前目录
      const templatePath = path.resolve(
        this.templateNpm.cacheFilePath,
        "template"
      );
      console.log(templatePath);
      targetPath = path.resolve(process.cwd(), "template"); // 当前目录
      fse.ensureDirSync(templatePath); // 确保目录存在
      fse.ensureDirSync(targetPath);
      fse.copySync(templatePath, targetPath); // 缓存目录 拷贝到 当前目录
      const templateIgnore = this.templateInfo.ignore || [];
      const ignore = ["**/node_modules/**", ...templateIgnore];
      await this.ejsRender({ ignore });
    } catch (error) {
      throw error;
    } finally {
      spinner.stop(true);
      log.success("模版安装成功");
    }
    // 依赖安装
    const { installCommand, startCommand } = this.templateInfo;
    // console.log('this.templateInfo', this.templateInfo);
    let installRes;
    if (installCommand) {
      const installCmd = installCommand.split(" ");
      const cmd = installCmd[0]; // 截取第一个参数
      const args = installCmd.slice(1); // 截取后面的参数
      console.log(targetPath, cmd, args, "dddddddddddddddddddd");
      installRes = await spawnAsyanc(cmd, args, {
        stdio: "inherit",
        cmd: targetPath,
      });
    }
    if (installRes !== 0) {
      // log.success('安装成功');
      throw new Error("安装模版失败");
    }
    // 启动命令执行
    if (startCommand) {
      const startCmd = startCommand.split(" ");
      const cmd = startCmd[0]; // 截取第一个参数
      const args = startCmd.slice(1); // 截取后面的参数
      await spawnAsyanc(cmd, args, {
        stdio: "inherit",
        cmd: targetPath,
      });
    }
  }
  ejsRender(options) {
    console.log(this.projectInfo);
    const cwd = process.cwd();
    return new Promise((resolve1, reject1) => {
      glob(
        "**",
        {
          cwd: cwd,
          ignore: options.ignore || "",
          nodir: true,
        },
        (err, files) => {
          if (err) {
            reject1(err);
          }

          Promise.all(
            files.map((file) => {
              const filePath = path.join(cwd, file);
              return new Promise((resolve2, reject2) => {
                ejs.renderFile(
                  filePath,
                  this.projectInfo,
                  {},
                  (err, result) => {
                    if (err) {
                      reject2(err);
                    }

                    fse.writeFileSync(filePath, result);
                    resolve2(result);
                  }
                );
              });
            })
          )
            .then(() => {
              resolve1();
            })
            .catch((err) => {
              reject1(err);
            });
        }
      );
    });
  }

  installCustomTemplate() {}
  // 目录有文件是否清空
  isDirEmpty(localPath) {
    let fileList = fs.readdirSync(localPath);
    fileList = fileList.filter(
      (file) => !file.startsWith(".") && !["node_modules"].includes(file)
    );
    return fileList.length === 0;
  }
}

function init(argv) {
  //   console.log(Array.from(arguments));
  return new InitCommand(argv);
  // TODO
  // console.log('init', arguments)
}

module.exports = init;
